package com.hy.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hy.common.Result;
import com.hy.dto.comment.CommentPageDTO;
import com.hy.dto.comment.CommentReplyDTO;
import com.hy.dto.comment.CommentWithRepliesDTO;
import com.hy.entity.Comment;
import com.hy.entity.User;
import com.hy.mapper.CommentMapper;
import com.hy.service.CommentService;
import com.hy.service.UserService;
import com.hy.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.HashMap;

@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Autowired
    private UserService userService;

    @Autowired
    private UserUtil userUtil;

    @Autowired
    private CommentMapper commentMapper;

    private CommentReplyDTO toDTO(Comment comment, Map<Integer, User> userMap) {
        CommentReplyDTO dto = new CommentReplyDTO();
        dto.setId(comment.getId());
        dto.setWeeklyId(comment.getWeeklyId());
        dto.setUserId(comment.getUserId());
        dto.setContent(comment.getContent());
        dto.setParentId(comment.getParentId());
        dto.setReplyId(comment.getReplyId());
        dto.setCreateTime(comment.getCreateTime());
        dto.setLikecount(comment.getLikecount()); // 添加点赞数赋值

        // 设置评论用户信息
        User user = userMap.get(comment.getUserId());
        if (user != null) {
            dto.setUserName(user.getName());
            dto.setUserAvatar(user.getAvatar());
        }

        // 如果是回复，设置被回复用户信息
        if (comment.getParentId() != null) {
            Comment parentComment = this.getById(comment.getParentId());
            if (parentComment != null) {
                User replyToUser = userMap.get(parentComment.getUserId());
                if (replyToUser != null) {
                    dto.setReplyToId(replyToUser.getId());
                    dto.setReplyToUserName(replyToUser.getName());
                }
            }
        }

        return dto;
    }

    @Override
    public Result<CommentPageDTO> getWeeklyComments(Long weeklyId, Long teacherId, Integer pageNum, Integer pageSize) {
        Page<Comment> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getDeleteFlag, 0)
                .isNull(Comment::getParentId)
                .orderByDesc(Comment::getCreateTime);
        if (ObjectUtil.isNotEmpty(weeklyId)) wrapper.eq(Comment::getWeeklyId, weeklyId);
        else wrapper.eq(Comment::getTeacherId, teacherId);

        Page<Comment> commentPage = this.page(page, wrapper);
        if (CollUtil.isEmpty(commentPage.getRecords())) return Result.success();

        // 获取用户ID并查询回复
        List<Integer> userIds = commentPage.getRecords().stream()
                .map(Comment::getUserId)
                .collect(Collectors.toList());
        List<Comment> allReplies = this.list(new LambdaQueryWrapper<Comment>()
                .eq(Comment::getDeleteFlag, 0)
                .isNotNull(Comment::getParentId)
                .in(Comment::getParentId, commentPage.getRecords().stream().map(Comment::getId).collect(Collectors.toList()))
                .orderByAsc(Comment::getCreateTime));

        // 处理回复关联
        Map<Integer, Comment> replyIdMap = new HashMap<>();
        allReplies.stream()
                .filter(reply -> reply.getReplyId() != null)
                .map(Comment::getReplyId)
                .distinct()
                .forEach(replyId -> replyIdMap.put(replyId, this.getById(replyId)));

        userIds.addAll(allReplies.stream().map(Comment::getUserId).collect(Collectors.toList()));
        Map<Integer, User> userMap = userService.listByIds(userIds).stream()
                .collect(Collectors.toMap(User::getId, user -> user, (k1, k2) -> k1));

        // 组装评论列表（移除回复数量限制）
        List<CommentWithRepliesDTO> commentList = commentPage.getRecords().stream()
                .map(comment -> {
                    CommentWithRepliesDTO vo = new CommentWithRepliesDTO();
                    vo.setComment(toDTO(comment, userMap));
                    vo.setReplies(allReplies.stream()
                            .filter(reply -> reply.getParentId().equals(comment.getId()))
                            .map(reply -> toDTO(reply, userMap))
                            .collect(Collectors.toList()));
                    return vo;
                })
                .collect(Collectors.toList());

        CommentPageDTO vo = new CommentPageDTO();
        vo.setTotal(commentPage.getTotal());
        vo.setComments(commentList);
        return Result.success(vo);
    }

    @Override
    public Result<Boolean> addComment(Comment comment) {
        Integer userId = userUtil.getUserIdFromToken();
        comment.setUserId(userId);
        comment.setDeleteFlag(0);
        comment.setCreateTime(new java.util.Date());
        comment.setUpdateTime(new java.util.Date());
        return Result.success(this.save(comment));
    }

    @Override
    public Result<CommentPageDTO> getCommentReplies(Long commentId, Integer pageNum, Integer pageSize) {
        Page<Comment> page = new Page<>(pageNum, pageSize);
        Page<Comment> replyPage = this.page(page, new LambdaQueryWrapper<Comment>()
                .eq(Comment::getParentId, commentId)
                .eq(Comment::getDeleteFlag, 0)
                .orderByAsc(Comment::getCreateTime));

        if (CollUtil.isEmpty(replyPage.getRecords())) return Result.success();

        // 获取用户ID及关联回复
        List<Integer> userIds = replyPage.getRecords().stream()
                .map(Comment::getUserId)
                .collect(Collectors.toList());
        Comment parentComment = this.getById(commentId);
        if (parentComment != null) userIds.add(parentComment.getUserId());

        // 处理回复关联
        Map<Integer, Comment> replyIdMap = new HashMap<>();
        replyPage.getRecords().stream()
                .filter(reply -> reply.getReplyId() != null)
                .map(Comment::getReplyId)
                .distinct()
                .forEach(replyId -> replyIdMap.put(replyId, this.getById(replyId)));

        userIds.addAll(replyIdMap.values().stream().map(Comment::getUserId).collect(Collectors.toList()));
        Map<Integer, User> userMap = userService.listByIds(userIds).stream()
                .collect(Collectors.toMap(User::getId, user -> user, (k1, k2) -> k1));

        // 组装回复列表
        List<CommentWithRepliesDTO> replyList = replyPage.getRecords().stream()
                .map(reply -> {
                    CommentWithRepliesDTO vo = new CommentWithRepliesDTO();
                    CommentReplyDTO replyDto = toDTO(reply, userMap);

                    // 处理回复目标
                    if (reply.getReplyId() != null) {
                        Comment replyToComment = replyIdMap.get(reply.getReplyId());
                        if (replyToComment != null) {
                            replyDto.setReplyToUserName(userMap.get(replyToComment.getUserId()).getName());
                        }
                    } else if (parentComment != null) {
                        replyDto.setReplyToUserName(userMap.get(parentComment.getUserId()).getName());
                    }

                    vo.setComment(replyDto);
                    return vo;
                })
                .collect(Collectors.toList());

        CommentPageDTO vo = new CommentPageDTO();
        vo.setTotal(replyPage.getTotal());
        vo.setComments(replyList);
        return Result.success(vo);
    }

    @Override
    public Result<CommentPageDTO> getStudyGardenComments(Long studyGardenId, Integer page, Integer size) {
        Page<Comment> commentPage = new Page<>(page, size);
        Page<Comment> mainCommentsPage = commentMapper.selectPage(commentPage, new LambdaQueryWrapper<Comment>()
                .eq(Comment::getStudyGardenId, studyGardenId)
                .eq(Comment::getDeleteFlag, 0)
                .isNull(Comment::getParentId)
                .orderByDesc(Comment::getCreateTime));

        if (CollUtil.isEmpty(mainCommentsPage.getRecords())) return Result.success(new CommentPageDTO());

        // 获取主评论的用户ID
        List<Integer> userIds = mainCommentsPage.getRecords().stream()
                .map(Comment::getUserId)
                .collect(Collectors.toList());

        // 获取回复评论的用户ID并添加到userIds
        List<Comment> allReplies = commentMapper.selectList(new LambdaQueryWrapper<Comment>()
                .eq(Comment::getStudyGardenId, studyGardenId)
                .eq(Comment::getDeleteFlag, 0)
                .isNotNull(Comment::getParentId)
                .in(Comment::getParentId, mainCommentsPage.getRecords().stream()
                        .map(Comment::getId)
                        .collect(Collectors.toList()))
                .orderByAsc(Comment::getCreateTime));

        // 合并所有用户ID
        userIds.addAll(allReplies.stream()
                .map(Comment::getUserId)
                .collect(Collectors.toList()));

        // 正确查询用户信息
        Map<Integer, User> userMap = userService.listByIds(userIds).stream()
                .collect(Collectors.toMap(User::getId, user -> user, (k1, k2) -> k1));

        // 组装评论与回复（包含点赞数）
        List<CommentWithRepliesDTO> commentList = mainCommentsPage.getRecords().stream()
                .map(comment -> {
                    CommentWithRepliesDTO dto = new CommentWithRepliesDTO();
                    dto.setComment(toDTO(comment, userMap));
                    dto.setReplies(allReplies.stream()
                            .filter(reply -> reply.getParentId().equals(comment.getId()))
                            .map(reply -> toDTO(reply, userMap))
                            .collect(Collectors.toList()));
                    return dto;
                })
                .collect(Collectors.toList());

        CommentPageDTO result = new CommentPageDTO();
        result.setTotal(mainCommentsPage.getTotal());
        result.setComments(commentList);
        result.setPage(page);
        result.setSize(size);
        return Result.success(result);
    }

    @Override
    public Result<Boolean> likeComment(Long commentId) {
        Comment comment = commentMapper.selectById(commentId);
        if (comment != null) {
            comment.setLikecount(comment.getLikecount() + 1);
            return Result.success(commentMapper.updateById(comment) > 0);
        }
        return Result.success(false);
    }

    @Override
    public Result<Boolean> DeleteComment(Long commentId) {
        Comment comment = commentMapper.selectById(commentId);
        if (comment != null) {
            comment.setLikecount(comment.getLikecount() - 1);
            return Result.success(commentMapper.updateById(comment) > 0);
        }
        return Result.success(false);
    }
}
